/**
 * @file request.js
 * @description 全局请求工具配置
 * @created 2024-06-25
 */

import axios from 'axios'
import { ElMessage } from 'element-plus'
import router from '@/router'

// 响应状态码错误信息
const statusCodeMessages = {
  400: '请求参数错误',
  401: '未授权，请重新登录',
  403: '拒绝访问',
  404: '请求的资源不存在',
  500: '服务器内部错误',
  502: '网关错误',
  503: '服务不可用',
  504: '网关超时'
}

/**
 * 创建axios实例
 * @description 配置全局请求参数
 */
const request = axios.create({
  // API的base_url，如果环境变量不存在则使用默认值
  baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000',
  // 请求超时时间
  timeout: 15000,
  // 添加withCredentials以支持跨域请求时发送cookie
  withCredentials: true
})

// 调试信息 - 输出当前baseURL设置
console.log('API请求baseURL:', request.defaults.baseURL);

// 添加调试函数，检查API端点是否可用
const checkApiEndpoints = async () => {
  console.log('开始检查API端点可用性...');

  const endpoints = [
    '/api/student/course/',
    '/api/student/course-selection/',
    '/api/student/course/progress/',
    '/api/student/course/notes/',
    '/api/student/course/collections/',
    '/api/student/course/wrong-questions/',
    '/api/student/course/tabs/',
    '/api/student/course/tab-content/'
  ];

  const results = {};

  for (const endpoint of endpoints) {
    try {
      // 使用HEAD请求而不是GET请求，不传递无效参数
      const response = await axios.head(`${request.defaults.baseURL}${endpoint}`, {
        timeout: 2000
      });
      console.log(`✅ API端点 ${endpoint} 可访问，状态: ${response.status}`);
      results[endpoint] = true;
    } catch (error) {
      const status = error.response ? error.response.status : '无响应';
      console.error(`❌ API端点 ${endpoint} 不可用，错误: ${status}`);
      results[endpoint] = false;
    }
  }

  console.log('API端点检查完成');
  return results;
};

// 检查单个API端点是否可用
const checkApiEndpoint = async (endpoint) => {
  try {
    const fullUrl = `${request.defaults.baseURL}${endpoint}`;
    console.log(`检查API端点: ${fullUrl}`);

    const response = await axios.head(fullUrl, {
      timeout: 2000
    });

    console.log(`✅ API端点 ${endpoint} 可访问，状态: ${response.status}`);
    return true;
  } catch (error) {
    const status = error.response ? error.response.status : '无响应';
    console.error(`❌ API端点 ${endpoint} 不可用，错误: ${status}`);
    return false;
  }
};

/**
 * 处理未授权状态（401）
 * @description 清除用户信息并重定向到登录页
 */
function handleUnauthorized() {
  // 清除本地存储的token和用户信息
  localStorage.removeItem('token')
  localStorage.removeItem('userInfo')
  localStorage.removeItem('permissions')

  // 重定向到登录页
  router.replace('/login')

  ElMessage.error('身份验证失败，请重新登录')
  console.warn('认证失败，已清除用户信息并重定向到登录页')
}

/**
 * 请求拦截器
 * @description 在请求发送前处理请求配置
 */
request.interceptors.request.use(
  config => {
    // 如果是学生相关的API接口
    if (config.url.includes('/api/student/')) {
      try {
        // 从localStorage获取学生用户信息
        const studentUserInfo = localStorage.getItem('studentUserInfo')

        if (studentUserInfo) {
          const userInfo = JSON.parse(studentUserInfo)

          // 如果是GET请求，添加查询参数
          if (config.method === 'get') {
            // 确保params对象存在
            config.params = config.params || {}

            // 添加学生ID作为查询参数
            if (userInfo.stu_id && !config.params.stu_id) {
              config.params.stu_id = userInfo.stu_id
            }

            // 添加用户名作为备选查询参数
            if (userInfo.username && !config.params.username) {
              config.params.username = userInfo.username
            }
          }
          // 如果是POST/PUT请求，添加到请求体
          else if (['post', 'put'].includes(config.method)) {
            // 确保data对象存在
            config.data = config.data || {}

            // 如果data是字符串（已经是JSON），则解析它
            if (typeof config.data === 'string') {
              try {
                config.data = JSON.parse(config.data)
              } catch (e) {
                // 如果解析失败，创建新对象
                config.data = {}
              }
            }

            // 添加学生ID
            if (userInfo.stu_id && !config.data.stu_id) {
              config.data.stu_id = userInfo.stu_id
            }
          }

          console.log('已添加学生用户信息到请求中')
        } else {
          console.log('未找到学生用户信息')
        }
      } catch (error) {
        console.error('添加用户信息到请求时出错:', error)
      }
    }
    // 其他API接口(管理员/教师)仍使用token认证
    else {
      // 从localStorage获取token
      const token = localStorage.getItem('token')

      // 如果存在token，则在请求头中添加Authorization
      if (token) {
        config.headers['Authorization'] = `Bearer ${token}`
        console.log('添加认证头:', `Bearer ${token.substring(0, 20)}...`)
      } else {
        console.warn('请求未携带token，可能导致认证失败')
      }
    }

    // 添加请求日志
    console.log('API请求 →', config.method.toUpperCase(), config.url, config.data || config.params)

    return config
  },
  error => {
    console.error('请求错误:', error)
    ElMessage.error('请求配置错误')
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器
 * @description 在接收响应前处理响应数据
 */
request.interceptors.response.use(
  response => {
    const res = response.data

    // 添加响应日志
    console.log('API响应 ←', response.config.method.toUpperCase(), response.config.url, res)

    // Django API直接返回数据的情况
    if (!res.hasOwnProperty('status')) {
      console.log('API返回原始数据（无status字段）', res)
      return res
    }

    // 如果响应状态不是success，则视为错误
    if (res.status !== 'success' && res.status !== 200) {
      // 显示错误消息
      ElMessage.error(res.message || '请求失败')

      // 401: 未授权或token过期
      if (response.status === 401 ||
          res.message?.includes('令牌无效') ||
          res.message?.includes('已过期')) {
        handleUnauthorized()
      }

      return Promise.reject(new Error(res.message || '请求失败'))
    }

    // 打印详细的成功响应数据
    console.log('API成功响应的数据: ', JSON.stringify(res).substring(0, 1000))

    // 返回响应数据
    return res
  },
  error => {
    console.error('响应错误:', error)

    // 处理网络错误或服务器错误
    if (error.response) {
      const status = error.response.status
      const errorMessage = error.response.data?.message || statusCodeMessages[status] || '请求失败'

      ElMessage.error(errorMessage)

      // 如果是未授权，执行清理和重定向
      if (status === 401) {
        handleUnauthorized()
      }
    } else if (error.request) {
      // 请求已发送但未收到响应
      console.error('请求已发送但未收到响应', error.request)
      ElMessage.error('网络异常，无法连接到服务器')
    } else {
      // 请求配置错误
      console.error('请求配置错误', error.message)
      ElMessage.error(`请求失败: ${error.message}`)
    }

    return Promise.reject(error)
  }
)

// 导出API端点检查功能和请求实例
export { checkApiEndpoints, checkApiEndpoint }
export default request

// 同时提供命名导出以保持兼容性
export { request }
